home *** CD-ROM | disk | FTP | other *** search
- /* new HyperCard XFCN to open/close index, context, and text files
- * copyright 1988 Mark ^Zimmermann - 880831-0904
- *
- * Call this XFCN as 'openCloseTEXfiles([optional list of numbers here])'.
- *
- * If the XFCN is called with no arguments, it puts up the standard files
- * dialog box and gives back in return the file refNums for the text
- * (document/dataspace) file, *.k, and *.p files, on one line, in
- * that order, separated by spaces. Note that the *.k and *.p files
- * must be in the same folder as the master dataspace file; an earlier
- * version of this XFCN tried to allow them to be elsewhere (or to
- * have different names), but it was too complex and didn't seem to be
- * appreciated by the users!
- *
- * If the XFCN is passed any numerical parameters, it attempts to
- * close them (assuming they are file refNums) and doesn't try to
- * open anything....
- *
- * If an error while opening a file seems to occur, the XFCN attempts
- * to close all files that have already been opened, and returns with
- * an error msg instead of the three file refNums. No error checking
- * is done on closing files, since there's not much that one could
- * do about such an error in any case....
- *
- */
-
-
- #include <MacTypes.h>
- #include <FileMgr.h>
- #include <StdFilePkg.h>
- #include <HyperXCmd.h>
-
- #define NULL 0
-
- /* define these to allow use of global variables in my XFCNs; a
- * Lightspeed C necessity, apparently...
- */
-
- #define SetUpA4() asm { move.l a4,-(sp) \
- move.l a0,a4 }
-
- #define RestoreA4() asm { move.l (sp)+,a4 }
-
-
- pascal void main (XCmdBlockPtr paramPtr);
- int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
- void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
- long atol (char *s);
- void ltoaR (char *ansp, long n, int maxDigits);
- int strlen (char *s);
- char *strcpy (char *s1, char *s2);
-
-
- pascal void main (paramPtr)
- XCmdBlockPtr paramPtr;
- {
- Str255 fileName;
- int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
- i, errNum;
- Handle answer;
-
- SetUpA4();
- if (paramPtr->paramCount != 0)
- {
- for (i = 0; i < paramPtr->paramCount; ++i)
- {
- refNum = atol (*(paramPtr->params[i]));
- FSClose (refNum);
- }
- RestoreA4();
- return;
- }
-
- if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
- {
- RestoreA4();
- return;
- }
-
- errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening text file!}");
- RestoreA4();
- return;
- }
-
- *(fileName + *fileName + 1) = '.';
- *(fileName + *fileName + 2) = 'k';
- *fileName += 2;
- errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- FSClose (textFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening index key (*.k) file!}");
- RestoreA4();
- return;
- }
-
- *(fileName + *fileName) = 'p';
- errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- FSClose (textFileRefNum);
- FSClose (keyFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening index ptr (*.p) file!}");
- RestoreA4();
- return;
- }
-
- if ((answer = NewHandle (20)) == NULL)
- {
- FSClose (textFileRefNum);
- FSClose (keyFileRefNum);
- FSClose (ptrFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, bad out of memory error in XFCN openTEXfiles call!}");
- RestoreA4();
- return;
- }
-
- ltoaR (*answer, textFileRefNum, 6);
- ltoaR (*answer + 6, keyFileRefNum, 6);
- ltoaR (*answer + 12, ptrFileRefNum, 6);
- *(*answer + 18) = '\0';
-
- paramPtr->returnValue = answer;
- RestoreA4();
- return;
- }
-
-
- /* this routine, adapted from the Lightspeed C 'MiniEdit' example, does
- * the standard files dialog routine to get the name of the text file
- * of the dataspace; other file names are gotten from that by putting
- * a '.k' or a '.p' at the end. This routine returns 1 if all is well,
- * or 0 if the user cancels out...
- */
-
- int zGetFile (fileNamePtr, volRefNumPtr, fileType)
- Str255 *fileNamePtr;
- int *volRefNumPtr;
- long fileType;
- {
- SFTypeList myFileTypes;
- Point SFGwhere;
- SFReply myReply;
- register int i;
-
- SFGwhere.v = 90;
- SFGwhere.h = 82;
- myFileTypes[0] = fileType;
-
- SFGetFile (SFGwhere, "\p", 0L, 1, myFileTypes, 0L, &myReply);
-
- if (myReply.good)
- {
- for (i = *myReply.fName; i >= 0; --i)
- (*fileNamePtr)[i] = myReply.fName[i];
- *volRefNumPtr = myReply.vRefNum;
- return (1);
- }
- else
- return (0);
- }
-
-
- /* function to set the return value of the XFCN to a chosen error msg;
- * if there isn't enough free memory to give us a Handle to the msg,
- * beep a bunch and then return!
- */
-
- void returnErrorMsg (paramPtr, msg)
- XCmdBlockPtr paramPtr;
- char *msg;
- {
- Handle answer;
- int msgLength;
-
- SysBeep (10);
- msgLength = strlen (msg);
- if ((answer = NewHandle (1 + msgLength)) == NULL)
- {
- SysBeep (10);
- SysBeep (10);
- SysBeep (10);
- SysBeep (10);
- SysBeep (10);
- return;
- }
-
- strcpy (*answer, msg);
- paramPtr->returnValue = answer;
- return;
- }
-
-
- /* function to convert alphanumeric string to a long int, from K&R & LSC
- * library.... simplified to avoid using isspace() & isdigit() ....
- */
-
- long atol (s)
- register char *s;
- {
- int signflag = 0;
- register long r = 0;
-
- while (*s == ' ')
- s++;
-
- if (*s == '-')
- {
- signflag = 1;
- s++;
- }
- else if (*s == '+')
- s++;
-
- while (*s >= '0' && *s <= '9')
- r = r * 10 + (*s++ - '0');
-
- return (signflag ? -r : r);
- }
-
-
- /* function to convert a number into a string of width maxDigits and
- * store it right-justified, blank-filled on left; based on K&R p. 60
- * example of itoa().
- *
- * Error handling: put a '>' or '<' in leading place to warn of an
- * overflow (no room for digits on a positive or negative number,
- * respectively), and put a '^' in leading place to warn if no room
- * for '-' sign on negative number...
- */
-
- void ltoaR (ansp, n, maxDigits)
- register char *ansp;
- register long n;
- int maxDigits;
- {
- register int i;
- long sign;
-
- i = maxDigits - 1;
- if ((sign = n) < 0)
- n = -n;
-
- do
- {
- ansp[i--] = n % 10 + '0';
- }
- while ((n /= 10) > 0 && i >= 0);
-
- if (i < 0 && n > 0) /* ran out of room with digits still to go */
- {
- if (sign > 0)
- ansp[0] = '>'; /* positive overflow signal */
- else
- ansp[0] = '<'; /* negative overflow signal */
- }
- else
- {
- if (sign < 0)
- if (i >= 0)
- ansp[i--] = '-';
- else
- ansp[0] = '^'; /* no room for '-' sign signal */
- for ( ; i >= 0; --i)
- ansp[i] = ' ';
- }
-
- return;
- }
-
-
- /* function to determine the length of a string ... standard thing,
- * adapted from the LSC library, and K&R p.98 ....
- */
-
- int strlen (s)
- register char *s;
- {
- char *s0 = s;
-
- while (*s++)
- ;
- return (s - s0 - 1);
- }
-
-
- /* function to copy a string from one place to another, in a rather
- * obvious fashion ... adapted from the LSC library, and K&R p.101 ....
- */
-
- char *strcpy (s1, s2)
- register char *s1, *s2;
- {
- char *s = s1;
-
- while (*s1++ = *s2++)
- ;
- return (s);
- }
-
-
-
-